/**
  ******************************************************************************
  * @file           : sysrcc.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"

extern void sys_gpio_init(void);
extern void sys_rtc_init(void);

/**
  * @brief System Clock Configuration
  * @retval None
  */
static void sys_rcc_init(void)
{
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
  while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_3)
  {
  }
  LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
  
  LL_RCC_HSE_Enable();
  while(LL_RCC_HSE_IsReady() != 1)
  {
  }
  
  LL_RCC_HSI_SetCalibTrimming(16);
  LL_RCC_HSI_Enable();
  while(LL_RCC_HSI_IsReady() != 1)
  {
  }
  
  LL_RCC_HSE_EnableCSS();
  
  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_4, 100, LL_RCC_PLLP_DIV_2);
  LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_4, 100, LL_RCC_PLLQ_DIV_4);
  
  LL_RCC_PLL_Enable();
  while(LL_RCC_PLL_IsReady() != 1)
  {
  }
  
  while(LL_PWR_IsActiveFlag_VOS() == 0)
  {
  }
  
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
  
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  {
  }
  
  LL_SetSystemCoreClock(100000000);

//  LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_PLLCLK, LL_RCC_MCO1_DIV_5);
  
  LL_RCC_SetTIMPrescaler(LL_RCC_TIM_PRESCALER_TWICE);
}

static void sys_ll_init(void)
{
  __IO uint32_t tmpreg;
  
  /* Enable the FLASH instruction cache. */
  FLASH->ACR |= FLASH_ACR_ICEN;
  /* Enable the FLASH data cache. */
  FLASH->ACR |= FLASH_ACR_DCEN;
  /* Enable the FLASH prefetch buffer. */
  FLASH->ACR |= FLASH_ACR_PRFTEN;
  
  NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
  
  tmpreg = 0x00u;
  SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);
  tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);
  UNUSED(tmpreg);
  
  tmpreg = 0x00u;
  SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);
  tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);
  UNUSED(tmpreg);
  
  NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
}

static void sys_dma_rcc_init(void)
{
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
}

void system_init(void)
{
  sys_ll_init();

  sys_rcc_init();

//  sys_rtc_init();

  sys_gpio_init();

//  sys_dma_init();

  rs232n1_uart_init();
  
  sys_dma_rcc_init();
}
